﻿// E-Book Copier
// Copyright (C) 2009 Chuan-Gen Fan
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Project: http://code.google.com/p/ebookcopier/
// Contact Author:
//    website: http://chuangen.name/
// e-mail/msn: chuangen@live.cn

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace EbookCopier
{
    /// <summary>
    /// 模拟鼠标点击
    /// </summary>
    [Cmder("{C1CBF072-A57A-46fe-8619-6EB5CF512BBF}", "模拟鼠标点击", HasEditableOptions = true)]
    public class MouseCmder : Cmder
    {
        /// <summary>
        /// 初始化类 <see cref="MouseCmder"/> 的新实例。
        /// </summary>
        public MouseCmder()
        {
            RefreshReaderState();
        }
        /// <summary>
        /// 显示设置对话框。
        /// </summary>
        /// <param name="dialogOwner">对话框的父窗体</param>
        public override void EditOptions(IWin32Window dialogOwner)
        {
            MouseCmderOptionsForm form = new MouseCmderOptionsForm(this);
            form.ShowDialog(dialogOwner);
        }

        #region 鼠标点击
        [DllImport("user32.dll")]
        static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, UIntPtr extraInfo);

        [Flags]
        enum MouseEventFlag : uint
        {
            Move = 0x0001,
            LeftDown = 0x0002,
            LeftUp = 0x0004,
            RightDown = 0x0008,
            RightUp = 0x0010,
            MiddleDown = 0x0020,
            MiddleUp = 0x0040,
            XDown = 0x0080,
            XUp = 0x0100,
            Wheel = 0x0800,
            VirtualDesk = 0x4000,
            Absolute = 0x8000
        }



        [DllImport("user32.dll")]
        static extern bool SetCursorPos(int X, int Y);


        /// <summary>
        /// 在当前鼠标的位置左键点击一下
        /// </summary>
        static void MouseClick()
        {
            mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
            mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);

        }
        /// <summary>
        /// 移动到坐标位置点击
        /// </summary>
        /// <param name="location">要点击的坐标位置,屏幕绝对值</param>
        static void MouseClick(Point location)
        {
            MouseMove(location);
            mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
            mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);

        }
        /// <summary>
        /// 移动到坐标位置
        /// </summary>
        static void MouseMove(Point location)
        {
            SetCursorPos(location.X, location.Y);
        }

        #endregion

        Point nextPageMouseLocation = Point.Empty;
        /// <summary>
        /// 获取或设置 下一页 按钮的鼠标点击位置。
        /// </summary>
        /// <value>下一页 按钮的鼠标点击位置。</value>
        public Point NextPageMouseLocation
        {
            get { return nextPageMouseLocation; }
            set
            {
                if (nextPageMouseLocation == value)
                    return;
                nextPageMouseLocation = value;

                base.OnPropertyChanged(EventArgs.Empty);
                RefreshReaderState();
            }
        }
        Point prevPageMouseLocation = Point.Empty;
        /// <summary>
        /// 获取或设置 上一页 按钮的鼠标点击位置。
        /// </summary>
        /// <value>上一页 按钮的鼠标点击位置。</value>
        public Point PrevPageMouseLocation
        {
            get { return prevPageMouseLocation; }
            set
            {
                if (prevPageMouseLocation == value)
                    return;
                prevPageMouseLocation = value;

                base.OnPropertyChanged(EventArgs.Empty);
                RefreshReaderState();
            }
        }
        bool flipByMouse = false;
        /// <summary>
        /// 使用 模拟鼠标 翻页。
        /// </summary>
        public bool FlipByMouse
        {
            get { return flipByMouse; }
            set { flipByMouse = value; }
        }
        /// <summary>
        /// 翻到上一页。
        /// </summary>
        public override void PrevPage()
        {
            if (prevPageMouseLocation == Point.Empty)
                return;

            MouseClick(prevPageMouseLocation);
        }
        /// <summary>
        /// 翻到下一页。
        /// </summary>
        public override void NextPage()
        {
            if (nextPageMouseLocation == Point.Empty)
                return;

            MouseClick(nextPageMouseLocation);
        }

        /// <summary>
        /// 刷新阅览器的状态。
        /// </summary>
        void RefreshReaderState()
        {
            ReaderState newState = ReaderState.Unknown;

            if (prevPageMouseLocation == Point.Empty || nextPageMouseLocation == Point.Empty)
                newState = ReaderState.RunningButNoDocument;
            else
                newState = ReaderState.RunningAndOpenDocument;

            if (readerState == newState)
                return;
            readerState = newState;
            base.OnReaderStateChanged(EventArgs.Empty);
        }

        /// <summary>
        /// 获取阅览器当前打开的文档标题。
        /// </summary>
        /// <returns>文档标题</returns>
        public override string GetDocumentTitle()
        {
            return "";
        }

        ReaderState readerState = ReaderState.Unknown;
        /// <summary>
        /// 获取阅览器的状态。
        /// </summary>
        /// <value>阅览器的状态。</value>
        public override ReaderState ReaderState
        {
            get { return readerState; }
        }
    }
}
